package com.crcc.common.util;

import java.awt.*;
import java.awt.Color;
import java.awt.Font;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Date;

import javax.imageio.ImageIO;
import javax.swing.*;

import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;


public class ExcleWaterMark {

    public static void main(String[] args) {
        try {
            setWaterMarkToXlsEt("中铁十九局集团", "", "", "");
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }

    public static void deleteFile(String fileName) {
        File file = new File(fileName);
        if (file.isFile() && file.exists()) {
            file.delete();
        }
    }

    public static boolean isRowEmpty(Row row) {
        for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++) {
            Cell cell = row.getCell(i);
            if (cell != null && cell.getCellType() != CellType.BLANK) {
                return false;
            }
        }
        return true;
    }

    public static FileNameVO setWaterMarkToXlsx(String watermarkText, String url, String url2, String name) throws Exception {
        FileNameVO fv = imageUtil.getFileXlsx(url, url2);
        XSSFWorkbook wb = new XSSFWorkbook(new FileInputStream(fv.getFile()));
        XSSFSheet sheet = wb.getSheetAt(0);//测试暂取第一个工作簿
        int h = 0;
        for (int j = 0; j <= sheet.getLastRowNum(); j++) {
            Row row = sheet.getRow(j);
            boolean f = isRowEmpty(row);
            if (!f) {
                h++;
            }
        }
        //添加水印
        int coloumNum = sheet.getRow(4).getPhysicalNumberOfCells();
        waterMarkExcel(wb, sheet, watermarkText, coloumNum * 60, h * 25);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        //设置密码
        sheet.protectSheet("inventory");
        wb.write(bos);
        wb.close();

        byte[] content = bos.toByteArray();
        OutputStream out = null;
        //out = new FileOutputStream("D:\\新建文件夹\\水印3.xls");
        File file = File.createTempFile(name, ".xlsx", new File(url2));
        out = new FileOutputStream(file);
        out.write(content);
        bos.close();
        out.close();
        FileNameVO fileNameVO = new FileNameVO();
        fileNameVO.setFile(file);
        fileNameVO.setFileName(file.getName());
        fileNameVO.setFileNameNew(fv.getFileName());
        return fileNameVO;
    }

    /**
     * xls、et(金山)添加水印
     *
     * @param watermarkText
     * @throws Exception
     */
    public static FileNameVO setWaterMarkToXlsEt(String watermarkText, String url, String url2, String name) throws Exception {
        //HSSFWorkbook wb = new HSSFWorkbook(new FileInputStream(WaterMarkWordUtils.filePath+"8.xls"));
        FileNameVO fv = imageUtil.getFileXls(url, url2);
        HSSFWorkbook wb = new HSSFWorkbook(new FileInputStream(fv.getFile()));
        HSSFSheet sheet = wb.getSheetAt(0);//测试暂取第一个工作簿
        int h = 0;
        for (int j = 0; j <= sheet.getLastRowNum(); j++) {
            Row row = sheet.getRow(j);
            boolean f = isRowEmpty(row);
            if (!f) {
                h++;
            }
        }
        //添加水印
        int coloumNum = sheet.getRow(4).getPhysicalNumberOfCells();
        waterMarkExcel(wb, sheet, watermarkText, coloumNum * 60, h * 25);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        //设置密码
        sheet.protectSheet("inventory");
        wb.write(bos);
        wb.close();

        byte[] content = bos.toByteArray();
        OutputStream out = null;
        //out = new FileOutputStream(WaterMarkWordUtils.filePath+"To8.xls");
        //out = new FileOutputStream("D:\\新建文件夹\\水印3.xls");
        File file = File.createTempFile(name, ".xls", new File(url2));
        out = new FileOutputStream(file);
        out.write(content);
        bos.close();
        out.close();
        FileNameVO fileNameVO = new FileNameVO();
        fileNameVO.setFile(file);
        fileNameVO.setFileName(file.getName());
        fileNameVO.setFileNameNew(fv.getFileName());
        return fileNameVO;
    }

    /**
     * @param wb
     * @param sheet 需要打水印的excel工作簿
     */
    private static void waterMarkExcel(Workbook wb, Sheet sheet, String watermarkText, int width, int height) throws Exception {
        ByteArrayOutputStream ByteArrayOut = new ByteArrayOutputStream();
        //加载图片
  		/*InputStream imageIn = new FileInputStream(imPath);
  		BufferedImage bufferImg = ImageIO.read(imageIn);*/
        BufferedImage bufferImg = getImage(watermarkText, width, height);
        ImageIO.write(bufferImg, "png", ByteArrayOut);
        //开始打水印
        Drawing drawing = sheet.createDrawingPatriarch();//
        /*
         * 参数定义：
         * 第一个参数是（x轴的开始节点）；
         * 第二个参数是（是y轴的开始节点）；
         * 第三个参数是（是x轴的结束节点）；
         * 第四个参数是（是y轴的结束节点）；
         * 第五个参数是（是从Excel的第几列开始插入图片，从0开始计数）；
         * 第六个参数是（是从excel的第几行开始插入图片，从0开始计数）；
         * 第七个参数是（图片宽度，共多少列）；
         * 第8个参数是（图片高度，共多少行）；
         */
        ClientAnchor anchor = drawing.createAnchor(1, 1, 2, 2, 1, 1, 2, 2);
        Picture pic = drawing.createPicture(anchor, wb.addPicture(ByteArrayOut.toByteArray(), Workbook.PICTURE_TYPE_PNG));
        pic.resize();

    }

    /**
     * 创建新的图片
     */
    public static BufferedImage getImage(String waterMarkContent, int width, int height) throws Exception {
        if (width < 500) {
            width = 500;
        }
        BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = (Graphics2D) bi.getGraphics();
        g2.setBackground(Color.WHITE);
        g2.clearRect(0, 0, width, height);
        return addWatermark(bi, waterMarkContent);
    }

    /**
     * 获取文本长度。汉字为1:1，英文和数字为2:1
     */
    private static int getTextLength(String text) {
        int length = text.length();
        for (int i = 0; i < text.length(); i++) {
            String s = String.valueOf(text.charAt(i));
            if (s.getBytes().length > 1) {
                length++;
            }
        }
        length = length % 2 == 0 ? length / 2 : length / 2 + 1;
        return length;
    }

    /**
     * @param sourceImgPath    源图片路径
     * @param waterMarkContent 水印内容
     * @description 生成水印图片
     */
    public static BufferedImage addWatermark(BufferedImage sourceImgPath, String waterMarkContent) {
        // 水印字体，大小
        Font font = new Font("宋体", Font.BOLD, 15);
        // 水印颜色
        Color markContentColor = Color.RED;
        // 设置水印文字的旋转角度
        Integer degree = 0;
        // 设置水印透明度
        float alpha = 0.2f;
        OutputStream outImgStream = null;
        try {
            // 文件转化为图片
            Image srcImg = sourceImgPath;
            // 获取图片的宽
            int srcImgWidth = srcImg.getWidth(null);
            // 获取图片的高
            int srcImgHeight = srcImg.getHeight(null);
            // 加水印
            BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
            // 得到画笔
            Graphics2D g = bufImg.createGraphics();
            g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
            // 设置水印颜色
            g.setColor(markContentColor);
            // 设置字体
            g.setFont(font);
            // 设置水印文字透明度
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
            if (null != degree) {
                // 设置水印旋转
                g.rotate(Math.toRadians(degree));
            }
            int x = -srcImgWidth / 2;
            int y = -srcImgHeight / 2;
            int markWidth = 20 * getTextLength(waterMarkContent);// 字体长度
            int markHeight = 20;// 字体高度

            // 循环添加水印
            while (x < srcImgWidth * 1.5) {
                y = -srcImgHeight / 2;
                while (y < srcImgHeight * 1.5) {
                    g.drawString(waterMarkContent, x, y);

                    y += markHeight + 160;
                }
                x += markWidth + 160;
            }
            // 释放资源
            g.dispose();
            return transferAlpha(bufImg);
        } catch (Exception e) {
            e.printStackTrace();
            e.getMessage();
        } finally {
            try {
                if (outImgStream != null) {
                    outImgStream.flush();
                    outImgStream.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
                e.getMessage();
            }
        }
        return null;
    }

    /**
     * @param bufImg 源图片
     * @description 转化成透明背景的图片
     */
    public static BufferedImage transferAlpha(BufferedImage bufImg) {

        try {
            Image image = bufImg;
            ImageIcon imageIcon = new ImageIcon(image);
            BufferedImage bufferedImage = new BufferedImage(imageIcon.getIconWidth(), imageIcon.getIconHeight(),
                    BufferedImage.TYPE_4BYTE_ABGR);
            Graphics2D g2D = (Graphics2D) bufferedImage.getGraphics();
            g2D.drawImage(imageIcon.getImage(), 0, 0, imageIcon.getImageObserver());
            int alpha = 0;
            for (int j1 = bufferedImage.getMinY(); j1 < bufferedImage.getHeight(); j1++) {
                for (int j2 = bufferedImage.getMinX(); j2 < bufferedImage.getWidth(); j2++) {
                    int rgb = bufferedImage.getRGB(j2, j1);
                    int R = (rgb & 0xff0000) >> 16;
                    int G = (rgb & 0xff00) >> 8;
                    int B = (rgb & 0xff);
                    if (((255 - R) < 30) && ((255 - G) < 30) && ((255 - B) < 30)) {
                        rgb = ((alpha + 1) << 24) | (rgb & 0x00ffffff);
                    }
                    bufferedImage.setRGB(j2, j1, rgb);
                }
            }
            g2D.drawImage(bufferedImage, 0, 0, imageIcon.getImageObserver());
            // 直接输出文件用来测试结果
            //ImageIO.write(bufImg, "png", new File("C:\\Users\\sunshine\\Desktop\\工作\\waterMark\\8-1.png"));
            return bufferedImage;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        }
        return null;
    }
}
